/* Copyright (c) CERN
 * * Artistic License 2.0
 * */

import java.util.Vector;
import java.io.*;

/**
 * This class must be called to generate stack distances from the trace of memory accesses.
 * For each memory access in the input file, there is a stack distance in the output file.
 * A stack distance of 0 means +infinity (first access).
 * It works both for instruction trace and data trace provided the input file contains memory addresses.
 *
 * usage: java Reuse input_file [output_file]
 *
 * @author Xavier Grehant
 */
class Reuse {

    public static void main(String args[]) {
        Vector<String> instr = new Vector<String>();
        Vector<Integer> distances = new Vector<Integer>();
        if (args.length >= 1) {
            try {
                // Open file
                FileInputStream fstream = new FileInputStream(args[0]);
                BufferedReader in = new BufferedReader(new InputStreamReader(fstream));

                // Create list of instructions and reuse distances
                String newInstr;
                while ((newInstr = in.readLine()) != null) {
                    int index = instr.lastIndexOf(newInstr);
                    instr.add(newInstr);
                    if (index == -1) {
                        // zero means first time used.
                        distances.add(0);
                    }
                    else {
                        // We mesure the reuse distance plus one.
                        distances.add(instr.size() - index);
                        instr.removeElementAt(index);
                    }
                }

                // Close file
                in.close();
            } catch (Exception e) {
                System.err.println("File input error");
            }

            // Write in new file.
            String filename = "reuse.out";
            if (args.length >= 2) filename = args[1];
            try {
                FileWriter fout = new FileWriter(new File(filename));
                for (Integer distance : distances) fout.write(distance + "\n");
                fout.close();
            } catch (IOException e) {
                System.out.println("Failed to write in file " + filename);
                e.printStackTrace();
            }
        }
        else
            System.out.println("Invalid parameters");
    }
}
